package com.easylinkin.linkappapi.machinery.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.common.model.RequestModel;
import com.easylinkin.linkappapi.common.utils.DateUtil;
import com.easylinkin.linkappapi.common.utils.NumberUtil;
import com.easylinkin.linkappapi.device.entity.Device;
import com.easylinkin.linkappapi.device.service.DeviceService;
import com.easylinkin.linkappapi.deviceattributestatus.entity.DeviceAttributeStatus;
import com.easylinkin.linkappapi.deviceattributestatus.service.DeviceAttributeStatusService;
import com.easylinkin.linkappapi.deviceunit.entity.DeviceUnit;
import com.easylinkin.linkappapi.deviceunit.service.DeviceUnitService;
import com.easylinkin.linkappapi.machinery.dto.MachineryIotDeviceDto;
import com.easylinkin.linkappapi.machinery.dto.TowerCraneWorkStatisticsDTO;
import com.easylinkin.linkappapi.machinery.entity.MachineryParameter;
import com.easylinkin.linkappapi.machinery.entity.TowerCraneCollisionAlarmRecord;
import com.easylinkin.linkappapi.machinery.entity.TowerCraneWorkRecord;
import com.easylinkin.linkappapi.machinery.mapper.MachineryRecordMapper;
import com.easylinkin.linkappapi.machinery.mapper.TowerCraneCollisionAlarmRecordMapper;
import com.easylinkin.linkappapi.machinery.mapper.TowerCraneWorkRecordMapper;
import com.easylinkin.linkappapi.machinery.service.ElevatorWorkRecordService;
import com.easylinkin.linkappapi.machinery.service.TowerCraneWorkRecordService;
import com.easylinkin.linkappapi.machinery.util.MachineryDeviceUtil;
import com.easylinkin.linkappapi.machinery.vo.CollisionAlarmRecordVO;
import com.easylinkin.linkappapi.machinery.vo.MachineryDeviceVo;
import com.easylinkin.linkappapi.machinery.vo.TowerCraneWorkStatisticsVO;
import com.easylinkin.linkappapi.openapi.dto.DatapushDTO;
import com.easylinkin.linkappapi.redis.RedisSync;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.shigongyun.service.MachineryMonitorBiService;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 塔吊工作循环记录 服务实现类
 * </p>
 *
 * @author Xiaoyang
 * @since 2022-08-14
 */
@Slf4j
@Service
public class TowerCraneWorkRecordServiceImpl extends ServiceImpl<TowerCraneWorkRecordMapper, TowerCraneWorkRecord>
		implements TowerCraneWorkRecordService {

	@Autowired
	private DeviceService deviceService;

	@Resource
	private MachineryRecordMapper machineryRecordMapper;

	@Resource
	private MachineryMonitorBiService machineryMonitorBiService;

	@Resource
	private LinkappUserContextProducer linkappUserContextProducer;

	@Resource
	private TowerCraneCollisionAlarmRecordMapper craneCollisionAlarmRecordMapper;

	@Resource
	private DeviceAttributeStatusService deviceAttributeStatusService;

	@Autowired
	private DeviceUnitService deviceUnitService;

	@Autowired
	private ElevatorWorkRecordService elevatorWorkRecordService;

	@Override
	public List<TowerCraneWorkRecord> getStatisticsList(TowerCraneWorkStatisticsVO statisticsVO) {
		String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
		statisticsVO.setTenantId(tenantId);
		List<TowerCraneWorkRecord> list = baseMapper.getList(statisticsVO);
		if (CollectionUtil.isNotEmpty(list)) {
			list = list.stream().sorted(Comparator.comparing(TowerCraneWorkRecord::getCreateTime))
					.collect(Collectors.toList());
		}
		return list;
	}

	@Override
	public Map<Integer, List<TowerCraneWorkStatisticsVO>> getStatisticsOrderByMachinery(
			TowerCraneWorkStatisticsVO statisticsVO) {
		String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
		List<Date> timeList = null;
		try {
			timeList = DateUtil.findDates(statisticsVO.getStartTime(), statisticsVO.getEndTime());
			if (CollectionUtil.isEmpty(timeList)) {
				return null;
			}
		} catch (ParseException e) {
			log.error("getStatisticsOrderByMachineryGlobal 群塔吊装 时间转换异常");
			throw new RuntimeException("getStatisticsOrderByMachineryGlobal 群塔吊装 时间转换异常" + e.getMessage());
		}
		String startTime = statisticsVO.getStartTime();
		String endTime = statisticsVO.getEndTime();
		Map<Integer, List<TowerCraneWorkStatisticsVO>> map = new HashMap<>();
		if (CollectionUtil.isEmpty(statisticsVO.getMachineryIotList())) {
			// 过滤设备号
			MachineryDeviceVo machineryDeviceVo = new MachineryDeviceVo();
			machineryDeviceVo.setTypeCode("QUIP_TSQZJ_01");
			machineryDeviceVo.setTenantId(tenantId);
			List<MachineryIotDeviceDto> allMachineryIotDeviceDtos = machineryMonitorBiService
					.selectMachineryAndDeviceByCondition(machineryDeviceVo);
			if (CollectionUtil.isNotEmpty(allMachineryIotDeviceDtos)) {
				statisticsVO.setMachineryIotList(allMachineryIotDeviceDtos);
			}
		}
		if (CollectionUtil.isNotEmpty(statisticsVO.getMachineryIotList())) {
			for (MachineryIotDeviceDto dto : statisticsVO.getMachineryIotList()) {
				TowerCraneWorkStatisticsVO req = new TowerCraneWorkStatisticsVO();
				req.setMachineryId(dto.getId());
				req.setCode(dto.getDeviceCode());
				req.setStartTime(startTime);
				req.setEndTime(endTime);
				req.setTenantId(tenantId);
				List<TowerCraneWorkStatisticsVO> dayList = getDayList(timeList, req);
				map.put(dto.getId(), dayList);
			}
		}
		return map;
	}

	@Override
	public List<TowerCraneWorkStatisticsVO> getStatisticsOrderByMachineryTop(TowerCraneWorkStatisticsVO statisticsVO) {
		String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
		statisticsVO.setTenantId(tenantId);
		List<TowerCraneWorkStatisticsVO> statisticsOrderByMachineryTop = baseMapper
				.getStatisticsOrderByMachineryTopGlobal(statisticsVO);
		// 进行数据填充
		MachineryDeviceVo machineryDeviceVo = new MachineryDeviceVo();
		machineryDeviceVo.setTypeCode("QUIP_TSQZJ_01");
		machineryDeviceVo.setTenantId(tenantId);
		List<MachineryIotDeviceDto> allMachineryIotDeviceDtos = machineryMonitorBiService
				.selectMachineryAndDeviceByCondition(machineryDeviceVo);
		List<String> machineNames = statisticsOrderByMachineryTop.stream().map(item -> item.getMachineryName())
				.collect(Collectors.toList());
		if (allMachineryIotDeviceDtos != null) {
			allMachineryIotDeviceDtos.stream().forEach(item -> {
				if (!machineNames.contains(item.getName())) {
					TowerCraneWorkStatisticsVO vo = new TowerCraneWorkStatisticsVO();
					vo.setMachineryName(item.getName());
					vo.setWorkCount(0);
					vo.setWeight(0d);
					vo.setPeriod(0d);
					vo.setWorkEfficiency(0d);
					statisticsOrderByMachineryTop.add(vo);
				}
			});
		}
		return statisticsOrderByMachineryTop;
	}

	@Override
	public TowerCraneWorkStatisticsDTO getStatisticsSum(TowerCraneWorkStatisticsVO statisticsVO) {
		TowerCraneWorkStatisticsDTO result = new TowerCraneWorkStatisticsDTO();
		result.setTowerCraneCount(0);
		result.setTowerCraneOnlineCount(0);
		result.setAvgWorkCount(0.0);
		result.setAvgWorkEfficiency(0.0);
		result.setAvgWorkWeight(0.0);
		result.setAvgCountWeight(0.0);
		// 塔吊监测数
		Integer all = 0;
		String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
		MachineryDeviceVo machineryDeviceVo = new MachineryDeviceVo();
		machineryDeviceVo.setTypeCode("QUIP_TSQZJ_01");
		machineryDeviceVo.setTenantId(tenantId);
		List<MachineryIotDeviceDto> allMachineryIotDeviceDtos = machineryMonitorBiService
				.selectMachineryAndDeviceByCondition(machineryDeviceVo);
		if (CollectionUtil.isNotEmpty(allMachineryIotDeviceDtos)) {
			all = allMachineryIotDeviceDtos.size();
			result.setTowerCraneCount(all);
		} else {
			return null;
		}
		// 在线数
		Integer online = 0;
		machineryDeviceVo.setOnlineState(1);
		List<MachineryIotDeviceDto> onlineMachineryIotDeviceDtos = machineryMonitorBiService
				.selectMachineryAndDeviceByCondition(machineryDeviceVo);
		if (CollectionUtil.isNotEmpty(onlineMachineryIotDeviceDtos)) {
			online = onlineMachineryIotDeviceDtos.size();
			result.setTowerCraneOnlineCount(online);
		}
		// 查询塔吊总数据
		List<String> codeList = allMachineryIotDeviceDtos.stream().map(MachineryIotDeviceDto::getDeviceCode)
				.collect(Collectors.toList());
		statisticsVO.setCodeList(codeList);
		statisticsVO.setTenantId(tenantId);
		TowerCraneWorkStatisticsVO statisticsSum = baseMapper.getStatisticsSum(statisticsVO);
		if (null != statisticsSum) {
			if (null != statisticsSum.getWorkCount()) {
				Double avgWorkCount = NumberUtil.div(statisticsSum.getWorkCount().doubleValue(), all.doubleValue(), 2);
				result.setAvgWorkCount(avgWorkCount);
			}
			if (null != statisticsSum.getWeight()) {
				Double avgWorkWeight = NumberUtil.div(statisticsSum.getWeight().doubleValue(), all.doubleValue(), 2);
				result.setAvgWorkWeight(avgWorkWeight);
			}
			// 平均单次吊重
			if (null != statisticsSum.getWorkCount() && null != statisticsSum.getWeight()) {
				Double avgCountWeight = NumberUtil.div(statisticsSum.getWeight().doubleValue(),
						statisticsSum.getWorkCount().doubleValue(), 2);
				result.setAvgCountWeight(avgCountWeight);
			}
			if (null != statisticsSum.getWorkEfficiency()) {
				Double avgWorkEfficiency = NumberUtil.doubleRoundHalfUp(statisticsSum.getWorkEfficiency(), 2);
				result.setAvgWorkEfficiency(avgWorkEfficiency);
			}
		}
		return result;
	}

	private List<TowerCraneWorkStatisticsVO> getDayList(List<Date> timeList, TowerCraneWorkStatisticsVO statisticsVO) {
		// 初始化
		List<TowerCraneWorkStatisticsVO> dayList = new ArrayList<>(timeList.size());
		FastDateFormat format = FastDateFormat.getInstance("yyyyMMdd");
		FastDateFormat format2 = FastDateFormat.getInstance("yyyy-MM-dd");
		// 查询统计
		List<TowerCraneWorkStatisticsVO> result = baseMapper.getStatisticsOrderByMachineryGlobal(statisticsVO);

		// 初始化数据
		Map<String, TowerCraneWorkStatisticsVO> resultMap = result.stream()
				.collect(Collectors.toMap(TowerCraneWorkStatisticsVO::getDay, Function.identity(), (k1, k2) -> k1));

		for (Date date : timeList) {
			String day = format.format(date);
			String refDate = format2.format(date);
			TowerCraneWorkStatisticsVO vo = null;
			if (null != resultMap && resultMap.containsKey(day)) {
				vo = resultMap.get(day);
				vo.setRefDate(refDate);
				String startTime = DateUtil.format(DateUtil.getCurrentDayMixDate(date),
						DateUtil.DATE_TIME_FORMAT_DEFAULT);
				String endTime = DateUtil.format(DateUtil.getCurrentDayMaxDate(date),
						DateUtil.DATE_TIME_FORMAT_DEFAULT);
				statisticsVO.setStartTime(startTime);
				statisticsVO.setEndTime(endTime);
				List<TowerCraneWorkRecord> list = baseMapper.getList(statisticsVO);
				if (CollectionUtil.isNotEmpty(list)) {
					TowerCraneWorkRecord startRecord = list.get(list.size() - 1);
					Date startWorkTime = startRecord.getStartTime();
					TowerCraneWorkRecord endRecord = list.get(0);
					Date endWorkTime = endRecord.getEndTime();
					Long workPeriodL = endWorkTime.getTime() - startWorkTime.getTime();
					Double workPeriod = NumberUtil.div(workPeriodL.doubleValue(), 60000d, 2);
					Double period = vo.getPeriod();
					Double orginalValue = NumberUtil.div(period, workPeriod, 2);
					Double workPercentage = NumberUtil.mul(orginalValue, 100d, 2);
					vo.setWorkPeriod(workPeriod);
					vo.setWorkPercentage(workPercentage);
//					if(vo.getLastEndTime()!=null && vo.getFirstStartTime()!=null){
//						vo.setTotalPeriod(String.format("%.2f", cn.hutool.core.date.DateUtil.between(vo.getFirstStartTime(),vo.getLastEndTime(), DateUnit.SECOND)/3600.0));
//					}
				}
			} else {
				vo = new TowerCraneWorkStatisticsVO();
				vo.setMachineryId(statisticsVO.getMachineryId());
				vo.setDay(day);
				vo.setWorkCount(0);
				vo.setPeriod(0.0);
				vo.setWeight(0.0);
				vo.setTotalPeriod("0.00");
				vo.setWorkEfficiency(0.0);
				vo.setRefDate(refDate);
			}
			dayList.add(vo);
		}
		if (CollectionUtil.isEmpty(dayList)) {
			return null;
		}
		for (TowerCraneWorkStatisticsVO p : dayList) {
			Date day = DateUtil.parse(p.getDay(), "yyyyMMdd");
			String refDate = DateUtil.format(day, DateUtil.DATE_TIME_FORMAT_DAY);
			p.setDay(refDate);
		}
		return dayList;
	}

	@Resource
	private RedisSync redisSync;

	private String getLockKey(String deviceCode) {
		// key = "redis_lock:towerCraneWorkRecord datapushHandler
		// lock2078635_redissync_end";
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		String key = "towerCraneWorkRecord datapushHandler lock";
		key += deviceCode;
		return key;
	}

	@Override
	public TowerCraneCollisionAlarmRecord selectTowerRealTimeData(Device device, Integer machineryId) {
		TowerCraneCollisionAlarmRecord collisionAlarmRecord = new TowerCraneCollisionAlarmRecord();
		DeviceUnit deviceUnit = deviceUnitService.getById(device.getDeviceUnitId());
		DeviceAttributeStatus status = new DeviceAttributeStatus();
		status.setDeviceCode(device.getCode());
		if (deviceUnit != null) {
			status.setVersion(deviceUnit.getVersion());
		}
		status.setTenantId(device.getTenantId());
		List<DeviceAttributeStatus> attrList = deviceAttributeStatusService.getDeviceRealtimeData(status);
		if (CollectionUtil.isEmpty(attrList)) {
			return collisionAlarmRecord;
		}
		Map<String, DeviceAttributeStatus> collect = attrList.stream().collect(
				Collectors.toMap(DeviceAttributeStatus::getPropCode, DeviceAttributeStatus -> DeviceAttributeStatus));
		collisionAlarmRecord.setMachineryId(machineryId);
		collisionAlarmRecord.setDeviceCode(device.getCode());
		collisionAlarmRecord.setTenantId(device.getTenantId());
		collisionAlarmRecord.setCreateTime(new Date());
		if (collect.containsKey("driver_name1")) {// 司机姓名
			String driverName = collect.get("driver_name1").getPropValue();
			collisionAlarmRecord.setDriverName1(driverName);
		}
		if (collect.containsKey("height")) {// 吊钩高度 单位m
			String height = collect.get("height").getPropValue();
			collisionAlarmRecord.setHeight(Double.parseDouble(height));
		}
		if (collect.containsKey("range")) {// 回转幅度 单位m
			String range = collect.get("range").getPropValue();
			collisionAlarmRecord.setRange(Double.parseDouble(range));
		}
		if (collect.containsKey("rotation")) {// 回转 单位°
			String rotation = collect.get("rotation").getPropValue();
			collisionAlarmRecord.setRotation(Double.parseDouble(rotation));
		}
		if (collect.containsKey("crane_arm_height")) {// 塔臂高 单位m
			String crane_arm_height = collect.get("crane_arm_height").getPropValue();
			collisionAlarmRecord.setCraneArmHeight(Double.parseDouble(crane_arm_height));
		}
		if (collect.containsKey("crane_fore_arm_length")) {// 前臂长 单位m
			String crane_fore_arm_length = collect.get("crane_fore_arm_length").getPropValue();
			collisionAlarmRecord.setCraneForeArmLength(Double.parseDouble(crane_fore_arm_length));
		}
		if (collect.containsKey("crane_rear_arm_length")) {// 后臂长 单位m
			String crane_rear_arm_length = collect.get("crane_rear_arm_length").getPropValue();
			collisionAlarmRecord.setCraneRearArmLength(Double.parseDouble(crane_rear_arm_length));
		}
		return collisionAlarmRecord;
	}

	@Override
	public List<MachineryIotDeviceDto> getTowerCraneDevice() {
		String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
		return elevatorWorkRecordService.getMachineryIotDeviceDtos(tenantId,"QUIP_TSQZJ_01");
	}

	@Override
	public Page getStatisticsDetailByMachinery(RequestModel<TowerCraneWorkStatisticsVO> requestModel) {
		//构造返回值
		Page page = new Page();

		//获取天数
		String startTime = requestModel.getCustomQueryParams().getStartTime();
		String endTime = requestModel.getCustomQueryParams().getEndTime();
		List<Date> timeList = null;
		try {
			timeList = DateUtil.findDates(startTime, endTime);
			if (CollectionUtil.isEmpty(timeList)) {
				return null;
			}
		} catch (ParseException e) {
			log.error("getStatisticsOrderByMachineryGlobal 塔吊 时间转换异常");
			throw new RuntimeException("getStatisticsOrderByMachineryGlobal 塔吊 时间转换异常" + e.getMessage());
		}

		//根据分页信息进行获取新的开始结束时间
		page.setSize(requestModel.getPage().getSize());
		page.setTotal(timeList.size());
		page.setPages((long) Math.ceil(timeList.size() / (double) requestModel.getPage().getSize()));
		long current = requestModel.getPage().getCurrent();
		long size = requestModel.getPage().getSize();
		List<Date> collect = timeList;
		//如果是-1的话就是全部
		if(size!=-1){
			collect = timeList.stream().skip((current - 1) * size).limit(size).collect(Collectors.toList());
		}

		if (CollectionUtil.isNotEmpty(collect)){
			//参数处理
			String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
			String code = requestModel.getCustomQueryParams().getCode();
			TowerCraneWorkStatisticsVO req = new TowerCraneWorkStatisticsVO();
//    req.setMachineryId(machineryId);
			req.setCode(code);
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			req.setStartTime(simpleDateFormat.format(collect.get(0)));
			Date date = collect.get(collect.size() - 1);
			//获取这个时间点的最后时间
			DateTime dateTime = cn.hutool.core.date.DateUtil.endOfDay(date);
			String format = simpleDateFormat.format(dateTime);
			req.setEndTime(format);
			req.setTenantId(tenantId);
			List<TowerCraneWorkStatisticsVO> dayList = getDayList(collect, req);

			//填充详细信息
			dayList.forEach(dayRecord->{
				String day = dayRecord.getDay();
				//获取这一天的开始结束时间
				String dayStartTime = day + " 00:00:00";
				String dayEndTime = day + " 23:59:59";
				req.setStartTime(dayStartTime);
				req.setEndTime(dayEndTime);
				List<TowerCraneWorkStatisticsVO> hourList= getHourList(req);
				int sum = hourList.stream().mapToInt(TowerCraneWorkStatisticsVO::getWorkCount).sum();
//				double periodSum = hourList.stream().mapToDouble(TowerCraneWorkStatisticsVO::getPeriod).sum();
				hourList.stream().filter(item->item.getFirstStartTime()!=null).mapToLong(item->item.getFirstStartTime().getTime()).min().ifPresent(item->{
					dayRecord.setFirstStartTime(new Date(item));
				});
				hourList.stream().filter(item->item.getLastEndTime()!=null).mapToLong(item->item.getLastEndTime().getTime()).max().ifPresent(item->{
					dayRecord.setLastEndTime(new Date(item));
				});
				dayRecord.setWorkCount(sum);
				dayRecord.setHourList(hourList);
				if(dayRecord.getFirstStartTime()!=null&&dayRecord.getLastEndTime()!=null){
					dayRecord.setTotalPeriod(String.format("%.2f",Math.round(cn.hutool.core.date.DateUtil.between(dayRecord.getFirstStartTime(),dayRecord.getLastEndTime(), DateUnit.SECOND) /36.0)/100.0));
				}else {
					dayRecord.setTotalPeriod("0.00");
				}
			});
			page.setRecords(dayList);
		}
		return page;
	}

	private List<TowerCraneWorkStatisticsVO> getHourList(TowerCraneWorkStatisticsVO statisticsVO) {
		// 查询统计
		List<TowerCraneWorkStatisticsVO> result = baseMapper.getStatisticsDetailByMachineryGlobal(statisticsVO);

		//填充没统计出来的数据
		List<String> times = result.stream().map(TowerCraneWorkStatisticsVO::getHour).collect(Collectors.toList());
		for (int i=0;i<24;i++) {
			String time = i<10?"0"+i:i+"";
			if (!times.contains(time)) {
				TowerCraneWorkStatisticsVO vo = new TowerCraneWorkStatisticsVO();
				vo.setHour(time);
				vo.setWorkCount(0);
				vo.setWeight(0.0);
				vo.setPeriod(0.0);
				result.add(vo);
			}
		}
		result.sort(new Comparator<TowerCraneWorkStatisticsVO>() {
			@Override
			public int compare(TowerCraneWorkStatisticsVO o1, TowerCraneWorkStatisticsVO o2) {
				return o1.getHour().compareTo(o2.getHour());
			}
		});
		return result;
	}

	@Override
	public void datapushHandler(DatapushDTO datapushDTO) {

		// 流水处理流程
		JSONObject data = datapushDTO.getData();
		String deviceCode = datapushDTO.getDevice_id();
		String lockKey = getLockKey(deviceCode);
		redisSync.tryAcquireRelease(lockKey, 300000, true, () -> {// 流水进行加锁处理
//				Device device = new Device();
//				device.setCode(deviceCode);
//				// 1.校验流水
//				// 1.1 校验是否属于塔机流水
//				List<Device> deviceList = deviceService.selectDevices(device);
//				if (deviceList == null || deviceList.size() <= 0) {
//					return;
//				}
//				device = deviceList.get(0);

			// 将查询逻辑放入主线程
			Device device = datapushDTO.getDevice_data_latest();

			String deviceUnitCodeConfigKey = "MACHINERY_TYPE_QUIP_TSQZJ_01";
			if (!MachineryDeviceUtil.isBelongSpecifiedDeviceType(device, deviceUnitCodeConfigKey)) {
				return;
			}
			// 1.2 校验流水是否关联电子档案
			MachineryDeviceVo machineryDeviceVo = new MachineryDeviceVo();
			machineryDeviceVo.setBinded(1);
			machineryDeviceVo.setTenantId(device.getTenantId());
			machineryDeviceVo.setDevice(device);
			// 查询关联的电子档案
			List<MachineryIotDeviceDto> ls = machineryRecordMapper.queryMachineryAndDeviceList(machineryDeviceVo);
			if (CollectionUtil.isEmpty(ls)) {
				return;
			}
			MachineryIotDeviceDto machineryIotDeviceDto = ls.get(0);
			// 1.3 流水消息类型
			Integer msgType = data.getInteger("msg_type");
			if (null == msgType) {
				return;
			}
			// 2.处理循环数据类型数据
			/**
			 * start_time end_time max_weight max_torque max_height min_height max_range
			 * min_range start_rotation start_range start_height end_rotation end_range
			 * end_height
			 */
			if (2 == msgType) {
				try {
					// 2.1 获取工作循环数据
					Date start_time = data.getDate("start_time");
					Date end_time = data.getDate("end_time");
					Double max_weight = data.getDouble("max_weight");
					Double max_torque = data.getDouble("max_torque");
					Double max_height = data.getDouble("max_height");
					Double min_height = data.getDouble("min_height");
					Double max_range = data.getDouble("max_range");
					Double min_range = data.getDouble("min_range");
					Double start_rotation = data.getDouble("max_weight");
					Double start_range = data.getDouble("start_range");
					Double start_height = data.getDouble("start_height");
					Double end_rotation = data.getDouble("end_rotation");
					Double end_range = data.getDouble("end_range");
					Double end_height = data.getDouble("end_height");

					// 2.2 塔机工作循环数据构造
					TowerCraneWorkRecord towerCraneWorkRecord = new TowerCraneWorkRecord();
					towerCraneWorkRecord.setMachineryId(machineryIotDeviceDto.getId());
					towerCraneWorkRecord.setDeviceCode(device.getCode());
					towerCraneWorkRecord.setTenantId(device.getTenantId());
					towerCraneWorkRecord.setCreateTime(new Date());
					towerCraneWorkRecord.setStartTime(start_time);
					towerCraneWorkRecord.setEndTime(end_time);
					towerCraneWorkRecord.setMaxWeight(max_weight);
					towerCraneWorkRecord.setMaxTorque(max_torque);
					towerCraneWorkRecord.setMaxHeight(max_height);
					towerCraneWorkRecord.setMinHeight(min_height);
					towerCraneWorkRecord.setMaxRange(max_range);
					towerCraneWorkRecord.setMinRange(min_range);
					towerCraneWorkRecord.setStartRotation(start_rotation);
					towerCraneWorkRecord.setStartRange(start_range);
					towerCraneWorkRecord.setStartHeight(start_height);
					towerCraneWorkRecord.setEndRotation(end_rotation);
					towerCraneWorkRecord.setEndRange(end_range);
					towerCraneWorkRecord.setEndHeight(end_height);

					DeviceUnit deviceUnit = deviceUnitService.getById(device.getDeviceUnitId());
					DeviceAttributeStatus status = new DeviceAttributeStatus();
					status.setDeviceCode(device.getCode());
					status.setTenantId(device.getTenantId());
					if (deviceUnit != null) {
						status.setVersion(deviceUnit.getVersion());
					}
					List<DeviceAttributeStatus> attrList = deviceAttributeStatusService
							.getDeviceRealtimeData(status);
					if (CollectionUtil.isNotEmpty(attrList)) {
						Map<String, DeviceAttributeStatus> collect = attrList.stream()
								.collect(Collectors.toMap(DeviceAttributeStatus::getPropCode,
										DeviceAttributeStatus -> DeviceAttributeStatus));
						if (collect.containsKey("driver_name1")) {
							String driverName = collect.get("driver_name1").getPropValue();
							towerCraneWorkRecord.setDriverName1(driverName);
						}

					}

					// 2.3 计算塔机载重百分比和力矩百分比
					List<MachineryParameter> machineryParameters = JSON
							.parseArray(machineryIotDeviceDto.getParameter(), MachineryParameter.class);
					if (CollectionUtil.isNotEmpty(machineryParameters)) {
						Double craneRatedLoad = null;// 塔机额定吊重
						Double craneRatedTorque = null;// 塔机额定力矩
						for (MachineryParameter parameter : machineryParameters) {
							String key = parameter.getKey();
							String value = parameter.getValue();
							if ("craneRatedLoad".equals(key) && StringUtils.isNotEmpty(value)) {
								craneRatedLoad = Double.parseDouble(parameter.getValue());

							}
							if ("craneRatedTorque".equals(key) && StringUtils.isNotEmpty(value)) {
								craneRatedTorque = Double.parseDouble(parameter.getValue());
							}
						}
						if (null != craneRatedLoad) {
							Double orginalValue = NumberUtil.div(max_weight, craneRatedLoad, 3);
							Double weightPercentage = NumberUtil.mul(orginalValue, 100d, 1);
							towerCraneWorkRecord.setWeightPercentage(weightPercentage);
						}
						if (null != craneRatedTorque) {
							Double orginalValue = NumberUtil.div(max_torque, craneRatedTorque, 3);
							Double torquePercentage = NumberUtil.mul(orginalValue, 100d, 1);
							towerCraneWorkRecord.setTorquePercentage(torquePercentage);
						}
					}
					// 2.4 入库
					baseMapper.insert(towerCraneWorkRecord);

				} catch (Exception e) {
					log.error("TowerCraneWorkRecord datapushHandler error:{}", e.getMessage());
				}

			}

			if (7 == msgType ) {// 报警、预警
				// 碰撞报警
				Integer collision_alarm_state = data.getInteger("collision_alarm_state");
				// 碰撞预警
				Integer collision_warn_state = data.getInteger("collision_warn_state");
				if ((null != collision_alarm_state && collision_alarm_state == 1) || (null != collision_warn_state && collision_warn_state == 1)) {

					TowerCraneCollisionAlarmRecord collisionAlarmRecord = selectTowerRealTimeData(device,
							machineryIotDeviceDto.getId());

					// 2.判断库里是否有上一次报警id
//            QueryWrapper<TowerCraneCollisionAlarmRecord> modelQueryWrapper = new QueryWrapper<>();
					// 设置查询条件
//            modelQueryWrapper.eq("tenant_id_", device.getTenantId())
//                .isNull("ref_record_id")
//                .orderByDesc("create_time_");
//            List<TowerCraneCollisionAlarmRecord> records = craneCollisionAlarmRecordMapper
//                .selectList(modelQueryWrapper);
					CollisionAlarmRecordVO towerCraneCollisionAlarmRecord = new CollisionAlarmRecordVO();
					towerCraneCollisionAlarmRecord.setTenantId(device.getTenantId());
					List<TowerCraneCollisionAlarmRecord> records = craneCollisionAlarmRecordMapper
							.selectByMachinery(towerCraneCollisionAlarmRecord);
					if (CollectionUtil.isNotEmpty(records)) {
						TowerCraneCollisionAlarmRecord previousCollisionAlarmRecord = records.get(0);
						if (null == collisionAlarmRecord) {
							return;
						}
						if (null == previousCollisionAlarmRecord.getRefRecordId()) {
							if (previousCollisionAlarmRecord.getMachineryId()
									.equals(collisionAlarmRecord.getMachineryId())
									&& previousCollisionAlarmRecord.getDeviceCode()
									.equals(collisionAlarmRecord.getDeviceCode())) {// 同一告警多次触发 直接返回不记录
								// 如果时间超过5分钟 开始记录新的
								long end = System.currentTimeMillis();
								long start = previousCollisionAlarmRecord.getCreateTime().getTime();
								long period = end - start;
								if (period > 5 * 60 * 1000) {
									craneCollisionAlarmRecordMapper.insert(collisionAlarmRecord);
								}
								return;
							}
							Long refRecordId = previousCollisionAlarmRecord.getId();
							collisionAlarmRecord.setRefRecordId(refRecordId);
						}
					}
					craneCollisionAlarmRecordMapper.insert(collisionAlarmRecord);

				}
			}
		});

	}

}
